package com.zyl.pool;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.*;

/**
 * @author zhaoyl
 * @date 2024/5/16 22:12
 * @description 说明
 */
public class ExecutorsTest {
    public static void main(String[] args) {
     /*   //只一个线程工作，相当于单线程串行执行。若此线程因异常而结束，会有新线程替代。保证任务的执行顺序按任务提交顺序执行。
        Executors.newSingleThreadExecutor();//创建一个单线程的线程池

        //提交一个任务创建一个线程，直到最大数。线程池数一旦达到最大值就会保持不变。若某线程因异常而结束，会有新线程替代。
        Executors.newFixedThreadPool(5);//创建固定大小的线程池。 5个

        //支持定时以及周期性执行任务的需求。
        Executors.newScheduledThreadPool(2);//创建一个固定大小的定时线程池。

        //支持定时以及周期性执行任务的需求。
        Executors.newSingleThreadScheduledExecutor();//创建一个单线程的定时线程池。

        //若线程池的数量超过了处理任务所需要的线程，就回收部分空闲（默认60秒不执行任务）的线程。当任务数增加时，此线程池又可以智能的添加新线程来处理任务
        //短时间内处理大量工作的线程池，会根据任务数量产生对应的线程，并试图缓存线程以便重复使用，如果限制 60 秒没被使用，则会被移除缓存。
        Executors.newCachedThreadPool();//创建一个可缓存的线程池*/
  /**-------------------------测试-----------------------------------------------*/
       // singleThreadExecutorTest();
        //fixedThreadPoolTest();
        //cachedThreadPoolTest();
        threadScheduledExecutorTest();
    }

    //newSingleThreadExecutor会使用同一个线程
    public static void singleThreadExecutorTest(){
        ExecutorService threadPool = Executors.newSingleThreadExecutor();
        try {
            for (int i=0;i<5;i++){
                threadPool.execute(()->{
                    System.out.println("创建线程->"+Thread.currentThread().getName());
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            threadPool.shutdown();//关闭
        }

    }

    //根据执行结果可以看出，newFixedThreadPool(2) 确实是创建了两个线程，在执行了一轮（2 次）之后，停了一秒，有了空闲线程，才执行第二轮..。
    public static void fixedThreadPoolTest(){

        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);

        for (int i = 0; i < 5; i++) {
            fixedThreadPool.execute(() -> {
                System.out.println("当前时间 - " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
                System.out.println("创建线程->"+Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    fixedThreadPool.shutdown();//关闭资源
                }
            });
        }
    }

    //创建多个（10个）
    public static void cachedThreadPoolTest(){
        ExecutorService threadPool = Executors.newCachedThreadPool();
        try {
            for (int i=0;i<10;i++){
                threadPool.execute(()->{
                    System.out.println("创建线程->"+Thread.currentThread().getName());
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            threadPool.shutdown();//关闭
        }
    }
    /**
     * newScheduledThreadPool()创建延迟处理任务的线程池,可以设置核心线程数,本例中为3
     * 调用schedule可以指定延迟处理的时间,处理任务的周期
     */
    public static void  threadScheduledExecutorTest(){
        // 创建一个线程池，它可以重用固定数量的线程，且在执行周期结束后会自动关闭
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);

            // 延迟1秒后执行任务
            executor.schedule(new Task("任务-1"), 1, TimeUnit.SECONDS);

            // 每隔2秒执行一次任务
            executor.scheduleAtFixedRate(new Task("任务-2"), 0, 2, TimeUnit.SECONDS);

            // 延迟3秒后开始执行，然后每隔5秒执行一次任务
            executor.scheduleWithFixedDelay(new Task("任务-3"), 3, 5, TimeUnit.SECONDS);

        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("时间到了关闭线程池->"+LocalDateTime.now().format(DateTimeFormatter.ofPattern("hh:mm:ss")));
                // 一定时间后关闭线程池
                executor.shutdown();
            }
        }, 3000);

        // 创建一个Runnable任务
        //  Runnable task = () -> System.out.println("Task executed at: " + System.nanoTime());

    }
    //任务处理
    static class Task implements Runnable {
        private String taskName;

        public Task(String taskName) {
            this.taskName = taskName;
        }
        @Override
        public void run() {
            System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("hh:mm:ss")) + " " + taskName + " 正在运行在线程-> " + Thread.currentThread().getName());
        }
    }

}

